package events

import (
	"gitee.com/yaodae/server-lib-go/log"
)

// EventPool 定义池类型
type EventPool struct {
	EntryChannel chan *Event // 对外接收Task的入口
	workerNum    int         // 协程池最大worker数量,限定Goroutine的个数
	JobsChannel  chan *Event //协程池内部的任务就绪队列
}

// 协程池创建一个worker并且开始工作
func (p *EventPool) worker(workId int) {
	defer func() {
		if r := recover(); r != nil {
			log.Error("捕获到的错误：%s\n", r)
		}
	}()
	// worker不断的从JobsChannel内部任务队列中拿任务
	for event := range p.JobsChannel {
		// 如果拿到任务,找出对应的监听器进行执行
		for name, listener := range eventListener {
			if name == event.Name {
				listener.Execute(workId, event.Value)
				break
			}
		}
	}
}

// Run 让协程池Pool开始工作
func (p *EventPool) Run() {
	//1,首先根据协程池的worker数量限定,开启固定数量的Worker,
	//  每一个Worker用一个Goroutine承载
	for i := 0; i < p.workerNum; i++ {
		go p.worker(i)
	}
	go func() {
		//2, 从EntryChannel协程池入口取外界传递过来的任务
		//   并且将任务送进JobsChannel中
		for event := range p.EntryChannel {
			p.JobsChannel <- event
		}
	}()
}

// Stop 让协程池Pool结束工作
func (p *EventPool) Stop() {
	// 执行完毕需要关闭JobsChannel
	close(p.JobsChannel)
	// 执行完毕需要关闭EntryChannel
	close(p.EntryChannel)
}
